#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sys.h"
#include "driver/gpio.h"

#include "m_http_client.h"
#include "m_ble.h"
#include "m_nvs.h"
#include "m_uart.h"
#include "m_led.h"
#include "m_config.h"
#include "m_http_client.h"

/* The examples use WiFi configuration that you can set via project configuration menu
   If you'd rather not, just change the below entries to strings with
   the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
*/
#define EXAMPLE_ESP_WIFI_SSID      "chenfei"
#define EXAMPLE_ESP_WIFI_PASS      "88888888"
#define EXAMPLE_ESP_MAXIMUM_RETRY  100

extern ble_esp32_param_t m_ble_esp32_param;

/* FreeRTOS event group to signal when we are connected*/
static EventGroupHandle_t s_wifi_event_group;
const int WIFI_CONNECTED_BIT = BIT0;
static const char *TAG = "M_WIFI";

static int s_retry_num = 0;
uint8_t isWifiConnectOk = 0;
extern xQueueHandle led_evt_queue;
extern led_status_e led_status;

static void event_handler(void* arg, esp_event_base_t event_base, 
                                int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) 
    {
        esp_wifi_connect();
    } 
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) 
    {
        ESP_LOGI(TAG,"connect to the AP fail");
        isWifiConnectOk = 0;
        if(led_status != led_status_wifi_connecting)
        {
            led_status = led_status_wifi_connecting;
            xQueueSend(led_evt_queue, &led_status, NULL);
        }

        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) 
        {
            esp_wifi_connect();
            xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        }
        else
        {
            ESP_LOGI(TAG, "can't reconnect to the AP, reset esp32 now");
            esp_restart();
        }
    } 
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) 
    {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "got ip:%s",
                 ip4addr_ntoa(&event->ip_info.ip));
        s_retry_num = 0;
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);

        isWifiConnectOk = 1;
        //http_connect_process();
    }
}

void wifi_init_sta(void)
{
    s_wifi_event_group = xEventGroupCreate();

    tcpip_adapter_init();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));


    wifi_config_t wifi_config;
    bzero(&wifi_config,sizeof(wifi_config_t));
    memcpy(wifi_config.sta.ssid,m_ble_esp32_param.ble_char1_WifiName,m_ble_esp32_param.ble_char1_WifiName_len);
    memcpy(wifi_config.sta.password,m_ble_esp32_param.ble_char2_WifiPassword,m_ble_esp32_param.ble_char2_WifiPassword_len);
    

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
    ESP_ERROR_CHECK(esp_wifi_start() );

    ESP_LOGI(TAG, "wifi_init_sta finished.");
    ESP_LOGW(TAG, "connect to ap  SSID:%s  password:%s",
             wifi_config.sta.ssid, wifi_config.sta.password);
}

void mWifi_init(void)
{
    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
    wifi_init_sta();
}



